#ifndef FLASH_H
#define FLASH_H
#include <stdint.h>

#define FLASH_PAGE_SIZE           ((uint16_t)0x1000U)	/* bank0 2kB each page */

/* FMC sector information */
typedef struct
{
    uint32_t sector_name;                                         /*!< the name of the sector */
    uint32_t sector_num;                                          /*!< the number of the sector */
    uint32_t sector_size;                                         /*!< the size of the sector */
    uint32_t sector_start_addr;                                   /*!< the start address of the sector */
    uint32_t sector_end_addr;                                     /*!< the end address of the sector */
} flash_sector_info_struct;

/* sector size */
#define SIZE_16KB                  ((uint32_t)0x00004000U)        /*!< size of 16KB*/
#define SIZE_64KB                  ((uint32_t)0x00010000U)        /*!< size of 64KB*/
#define SIZE_128KB                 ((uint32_t)0x00020000U)        /*!< size of 128KB*/
#define SIZE_256KB                 ((uint32_t)0x00040000U)        /*!< size of 256KB*/

/* FMC BANK address */
#define FLASH_START_ADDRESS          FLASH_BASE                               /*!< FMC start address */
#define FLASH_BANK0_START_ADDRESS    FLASH_START_ADDRESS                      /*!< FMC BANK0 start address */
#define FLASH_BANK1_START_ADDRESS    ((uint32_t)0x08100000U)                  /*!< FMC BANK1 start address */
#define FLASH_SIZE                   (*(uint16_t *)0x1FFF7A22U)               /*!< FMC SIZE */
#define FLASH_END_ADDRESS            (FLASH_BASE + (FLASH_SIZE * 1024) - 1)   /*!< FMC end address */
#define FLASH_MAX_END_ADDRESS        ((uint32_t)0x08300000U)                  /*!< FMC maximum end address */

/* FMC error message */
#define FLASH_WRONG_SECTOR_NAME      ((uint32_t)0xFFFFFFFFU)        /*!< wrong sector name*/
#define FLASH_WRONG_SECTOR_NUM       ((uint32_t)0xFFFFFFFFU)        /*!< wrong sector number*/
#define FLASH_INVALID_SIZE           ((uint32_t)0xFFFFFFFFU)        /*!< invalid sector size*/
#define FLASH_INVALID_ADDR           ((uint32_t)0xFFFFFFFFU)        /*!< invalid sector address*/

#define FLASH_PARA_ADDR                  (0x08004000) /*参数基地址*/
#define FLASH_PARA_SIZE                  (16 * KB)
#define USER_DATA_ADDR_BASE              (FLASH_PARA_ADDR + 0*FLASH_PAGE_SIZE)/*0x08004000~0x08004FFF,用户参数存储*/
#define DOWNLOAD_DATA_ADDR_BASE          (FLASH_PARA_ADDR + 1*FLASH_PAGE_SIZE)/*0x08005000~0x08005FFF，下载程序标志存储位置*/
#define PWMI_CALIBRATION_DATA_ADDR_BASE  (FLASH_PARA_ADDR + 2*FLASH_PAGE_SIZE)/*0x08006000~0x08006FFF，PWMI标定参数存储位置*/
#define USER_STORE_PARAMETER_ADDR_BASE   (FLASH_PARA_ADDR + 3*FLASH_PAGE_SIZE)/*0x08007000~0x08007FFF，用户参数存储位置*/

void Flash_read_32bit_data(uint32_t address, uint16_t length, int32_t *data_32);
int Flash_write_32bit_data_with_sector_erased(uint32_t address, uint16_t length, const uint32_t *data_32);


void Flash_read_8bit_data(uint32_t address, uint16_t length, uint8_t *data_8);

void Flash_erase_sector_by_address(uint32_t address);

/**
 * @brief 擦除一页，每页大小4KB
 * @param[in] address: 页起始地址
 */
void Flash_erase_page(uint32_t address);

int Flash_write_16bit_data_with_sector_erased(uint32_t address, uint16_t length, const uint16_t *data_16);
/**
 * @brief 读取指定地址的16位数据
 * @param address 地址
 * @param length 读取长度
 * @param data_16 数据指针
 */
void Flash_read_16bit_data(uint32_t address, uint16_t length, uint16_t *data_16);


#endif
